package com.demon.activitychange.persist.impl;

import android.os.Environment;
import android.support.annotation.NonNull;
import android.text.TextUtils;

import com.demon.activitychange.persist.IPersist;
import com.demon.activitychange.xposed.HookMain;

import org.json.JSONObject;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class FilePersist implements IPersist {

    private static final String path = Environment.getExternalStorageDirectory() + "/Android/data/%s/bytedance/";
    private JSONObject mObj;
    private File mFile;
    private static FilePersist mPersist;

    private FilePersist(String packageId) {
        mFile = new File(String.format(path, packageId) + FILE_NAME + ".txt");
    }

    public static FilePersist getInstance(String packageId) {
        if (mPersist == null) {
            synchronized (FilePersist.class) {
                if (mPersist == null) {
                    mPersist = new FilePersist(packageId);
                }
            }
        }
        return mPersist;
    }

    public static FilePersist newInstance(String packageId) {
        return new FilePersist(packageId);
    }

    @Override
    public synchronized boolean writeData(String key, Object value) {
        boolean isSuccess = true;
        String content = "";
        JSONObject obj = new JSONObject();

        try {
            content = read();
            if (TextUtils.isEmpty(content)) {
                obj = new JSONObject();
            } else {
                obj = new JSONObject(content);
            }
            obj.put(key, value);
            write(obj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            isSuccess = false;
        }

        if (isSuccess) {
            mObj = obj;
            return true;
        }
        return false;
    }

    @Override
    public synchronized Object readData(String key, Object defaultValue) {
        try {
            if (mObj == null) {
                String content = read();
                if (TextUtils.isEmpty(content)) {
                    mObj = new JSONObject();
                } else {
                    mObj = new JSONObject(content);
                }
            }
            return mObj.has(key) ? mObj.get(key) : defaultValue;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return defaultValue;
    }

    @Override
    public synchronized boolean clearData(String key) {
        boolean isSuccess = true;
        String content = "";
        JSONObject obj = new JSONObject();

        try {
            content = read();
            if (TextUtils.isEmpty(content)) {
                obj = new JSONObject();
            } else {
                obj = new JSONObject(content);
            }
            obj.remove(key);
            write(obj.toString());
        } catch (Exception e) {
            e.printStackTrace();
            isSuccess = false;
        }

        if (isSuccess) {
            mObj = obj;
            return true;
        }
        return false;
    }

    @Override
    public synchronized boolean clearDatas() {
        if (mFile.exists()) {
            mObj = null;
            return mFile.delete();
        }

        return false;
    }

    private void write(@NonNull String content) throws Exception {
        File dir = mFile.getParentFile();
        if (!dir.exists()) {
            dir.mkdirs();
        }
        if (!mFile.exists()) {
            mFile.createNewFile();
        }

        FileWriter fw = new FileWriter(mFile);
        char[] data = content.toCharArray();
        try {
            fw.write(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
        fw.close();
    }

    private String read() throws Exception {
        if (!mFile.exists()) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        FileReader fr = new FileReader(mFile);
        char[] buffer = new char[1024];

        try {
            int len;
            while ((len = fr.read(buffer)) != -1) {
                if (len > 0) {
                    for (int i = 0; i < len; i++) {
                        sb.append(buffer[i]);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        fr.close();
        return sb.toString();
    }
}
